package com.example.myBatisDemo.ch;


import com.example.myBatisDemo.ch.been.Dynamic;
import com.example.myBatisDemo.ch.been.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import javax.jws.HandlerChain;
import javax.jws.soap.SOAPBinding;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Date;
import java.util.*;

public class MyBatisJDBC {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);

            sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //获取SqlSession连接
    public static SqlSession getSession(){
        //openSession()没参数不自动提交
        return sqlSessionFactory.openSession();//需要手动提交
//        return sqlSessionFactory.openSession(true);//自动提交
    }
    public static void main(String[] args)  {


        动态SQL();
    }

    private static void 缓存() {
        /**
         * 一级缓存失效情况(没有使用到当前一级缓存的情况，效果就是，还需要再向数据库发出查询) ;
         *      1、sqlSession不同。
         *      2、sqlSession相同，查询条件不同。(当前一级缓存中还没有这个数据)
         *      3、sqlSession相同，两次查询之间执行了增删改操作(这次增删改可能对当前数据有影响)
         *      4、sqlSession相同，手动清除了一级缓存(缓存清空)
         *
         * 二级缓存: (全局缓存)基于namespace级别的缓存，一个namespace对应一 个二级缓存:
         * 工作机制:
         *  1、-一个会话，查询-条数据，这个数据重会被放在当前会话的一 级缓存中:
         *  2、如果会话关闭: -级缓存中的数据会被保存到二级缓存中:新的会话查询信息，就可以参照二级缓存中的内容
         *  3、sqlSession===      Mapper==>JavaBeen
         *      不同namespace查出的数据会放在自己对应的缓存中(map)
         *
         *      效果:数据会从二级缓存中获取
         *          查出的数据都会被默认先放在一级缓存中。
         *          只有会话提交或者关闭以后，- -级缓存中的数据才会转移到二级缓存中
         *
         *  1.先在mybatis-config.xml配置文件中开启二级缓存  <setting name="cacheEnabled" value="true"/>
         *  2.在Mapper.xml文件中配置二级缓存
         *  3.我们的POJO（JavaBeen）需要实现序列化接口
         *
         *  和缓存有关的设置/属性:（一级缓存一直存在）
         *      1)、cacheEnabled=true: false:关闭缓存(二级缓存关闭)
         *      2)、每个select标签都有useCache= "true".
         *          false:不使用援存()（影响二级缓存）
         *      3)、每个增删改标签的: flushCache= "true":（一级和二级都会清除）
         *          增册改执行完成后就会清除缓存
         *          测试: flushCache= "true": - -级缓存就清空了:二级也会被清除;
         *          查询标签: flushCache= "false":
         *          如果flushCache=true;每次查询之前都会清空缓存:缓存是相当于没有被使用的:
         *      4)、sqlSession.clearCache();//清除一级缓存
         *      4)、localCacheScope;
         *          本地缓存作用域: (一级缓存SESSION（默认）) ;当前会话的所有数据保存在会话缓存中
         *                      STATEMENT.可以禁用一级缓存:
         */
        SqlSession sqlSession = getSession();
        try {
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            User users = userMapper.getUserid(1);//连续查询
            sqlSession.clearCache();//清除缓存
            User users2 = userMapper.getUserid(1);//连续查询
            System.out.println(users);
            System.out.println(users2);
            System.out.println(users2==users);//true
            // 缓存  两个相同的Sql只用执行一次  但是只限于同一个SqlSession对象
        }finally {
            sqlSession.close();
        }
    }

    private static void 动态SQL() {
        SqlSession sqlSession = getSession();//代表一次和数据库的一次绘画
        //线程不安全  不能共享
        try {
            dynamicMapper dynamicM = sqlSession.getMapper(dynamicMapper.class);
            Dynamic dynamic = new Dynamic();
//            dynamic.setId(0);
            dynamic.setAge(18);
//            dynamic.setData(new Date());
            dynamic.setName("张%");
            dynamic.setSex(1);
//            dynamicM.getDynamicList(dynamic).stream().forEach(System.out::println);
//            dynamicM.getDynamicChoose(dynamic).stream().forEach(System.out::println);
//            dynamicM.getDynamicChoose(new Dynamic()).stream().forEach(System.out::println);

//            System.out.println(dynamicM.updateDynamic(new Dynamic(2, "张娇龙", null,new java.sql.Date(90,10,10), null)));


            List<Integer> list = Arrays.asList(1,2,4,5);
//            dynamicM.getDynamicForEach(list).stream().forEach(System.out::println);
            List<Dynamic> lists = new ArrayList<>();
            lists.add(new Dynamic(null, "天下第一", 20,new java.sql.Date(100,3,14), 1));
            lists.add(new Dynamic(null, "天下第", 66,new java.sql.Date(75,7,6), 1));
            lists.add(new Dynamic(null, "天下", 2,new java.sql.Date(121,10,14), 1));
//            System.out.println(dynamicM.addDynamicList(lists));

            dynamic.setName("天下");
            dynamicM.MysqlOrOracle(dynamic).stream().forEach(System.out::println);
            dynamicM.MysqlOrOracle(null).stream().forEach(System.out::println);
        }finally {
            sqlSession.close();
        }
    }

    private static void 接口代理对数据库操作() {
        SqlSession sqlSession = getSession();//代表一次和数据库的一次绘画
        //线程不安全  不能共享
        try {
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//            User user = userMapper.getUseridList(1);//查询
            User users = userMapper.getUserid(1);//连续查询
            System.out.println(users);
//            User userOne = userMapper.loginOne("毛纪","666");
//            System.out.println(userOne);
            User user1 = new User();
            user1.setUsername("apc1");
            user1.setPassword("apc1");
//            userMapper.addUser(user1);//添加
//            System.out.println(user1.getId());
//            userMapper.updateUser(new User(1,"龙","6379"));//修改
//            System.out.println(userMapper.deleteUser(3));

//            System.out.println(userMapper.getUser());//查询所有
//            System.out.println(userMapper.getUserResultMapW());//ResultMap自定义
//            Map<Integer, User> userMap = userMapper.getUserMap();//返回Map形式的数据
//            System.out.println(userMap);
//            sqlSession.commit();//手动提交

//            用map插入数据
//            Map<String,String> map = new HashMap<>();
//            map.put("username","易成龙");
//            map.put("password","677");
//            userMapper.addUser(map);

        }finally {
            sqlSession.close();
        }
    }

    private static void 老方法() throws IOException {
        /**
         * 不需要接口  代理
         */
        SqlSession sqlSession = getSession();
        try {
            User user = sqlSession.selectOne("com.example.myBatisDemo.ch.UserMapper.getUserid",2);
            System.out.println(user);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            sqlSession.close();
        }
    }

}
